import os
import time
import psutil
import threading
import logging
from datetime import datetime
from sinotrans.core import FileProcessor
import gc

class SimpleMemoryMonitor:
    """简化内存监控类 - 仅监控不优化"""
    
    def __init__(self, monitor_interval: int = 30, gc_threshold=0.9):
        """
        初始化简化内存监控器
        :param monitor_interval: 监控间隔（秒）
        """
        self.monitor_interval = monitor_interval
        self.monitoring_active = False
        self.monitor_thread = None
        self._lock = threading.Lock()
        self.gc_threshold = gc_threshold

        # 监控目标
        self.monitored_threads = {}  # {thread_name: thread_object}
        self.monitored_queues = {}   # {queue_name: queue_object}

        self._init_logger()
    def _init_logger(self):
        """初始化内存监控专用日志系统"""
        current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        debug_path = os.path.join(current_dir, "logs", "memory")
        FileProcessor.ensure_directories_exist([debug_path])
        
        # 创建内存监控专用的logger
        self.memory_logger = logging.getLogger('memory_monitor')
        self.memory_logger.setLevel(logging.INFO)
        
        # 避免重复添加handler
        if not self.memory_logger.handlers:
            # 创建文件handler
            log_file = os.path.join(debug_path, f"memory_monitor_{datetime.now().strftime('%Y%m%d%H%M%S')}.log")
            file_handler = logging.FileHandler(log_file, encoding='utf-8')
            file_handler.setLevel(logging.DEBUG)
            
            # 创建formatter
            formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
            file_handler.setFormatter(formatter)
            
            # 添加handler到logger
            self.memory_logger.addHandler(file_handler)
    def start_monitoring(self):
        """启动内存监控"""
        if not self.monitoring_active:
            self.monitoring_active = True
            self.monitor_thread = threading.Thread(target=self._monitor_worker, daemon=True)
            self.monitor_thread.start()
            self.memory_logger.info(f"📊 简化内存监控已启动 - 监控间隔: {self.monitor_interval}秒")
    
    def stop_monitoring(self):
        """停止内存监控"""
        self.monitoring_active = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=5)
        self.memory_logger.info("📊 简化内存监控已停止")
    
    def register_thread(self, thread_name: str, thread_obj: threading.Thread):
        """注册需要监控的线程"""
        with self._lock:
            self.monitored_threads[thread_name] = thread_obj
            self.memory_logger.info(f"📝 已注册监控线程: {thread_name}")
    
    def register_queue(self, queue_name: str, queue_obj):
        """注册需要监控的队列"""
        with self._lock:
            self.monitored_queues[queue_name] = queue_obj
            self.memory_logger.info(f"📝 已注册监控队列: {queue_name}")
    
    def unregister_thread(self, thread_name: str):
        """取消注册线程"""
        with self._lock:
            if thread_name in self.monitored_threads:
                del self.monitored_threads[thread_name]
                self.memory_logger.info(f"📝 已取消监控线程: {thread_name}")
    
    def unregister_queue(self, queue_name: str):
        """取消注册队列"""
        with self._lock:
            if queue_name in self.monitored_queues:
                del self.monitored_queues[queue_name]
                self.memory_logger.info(f"📝 已取消监控队列: {queue_name}")
    
    def _monitor_worker(self):
        """监控工作线程 - 简化版本"""
        while self.monitoring_active:
            try:
                memory_percent = psutil.virtual_memory().percent / 100.0
                
                # 超过80%立即触发GC
                if memory_percent >= self.gc_threshold:
                    self._force_garbage_collection(memory_percent)
                
                self._log_system_memory()
                self._log_thread_memory()
                self._log_queue_status()
                time.sleep(self.monitor_interval)
                
            except Exception as e:
                self.memory_logger.error(f"❌ 内存监控异常: {str(e)}")
                
    def _force_garbage_collection(self, memory_percent):
        """强制垃圾回收"""
        self.memory_logger.warning(f"🗑️ 内存使用率 {memory_percent:.1%}，强制GC")
        
        # 连续执行3轮GC
        for i in range(3):
            collected = gc.collect()
            if collected > 0:
                self.memory_logger.info(f"GC第{i+1}轮: 清理 {collected} 个对象")
        
        # 记录GC效果
        new_memory = psutil.virtual_memory().percent / 100.0
        freed = (memory_percent - new_memory) * 100
        self.memory_logger.info(f"GC完成，new_memory:{new_memory}，释放内存: {freed:.1f}%")
    
    def _log_system_memory(self):
        """记录系统内存使用情况"""
        try:
            memory = psutil.virtual_memory()
            process = psutil.Process()
            
            self.memory_logger.info(
                f"💾 系统内存: 总计={memory.total/1024/1024/1024:.1f}GB, "
                f"已用={memory.used/1024/1024/1024:.1f}GB ({memory.percent:.1f}%), "
                f"可用={memory.available/1024/1024/1024:.1f}GB, "
                f"当前进程={process.memory_info().rss/1024/1024:.1f}MB"
            )
        except Exception as e:
            self.memory_logger.error(f"❌ 记录系统内存失败: {e}")
    
    def _log_thread_memory(self):
        """记录线程内存使用情况"""
        with self._lock:
            active_threads = []
            for thread_name, thread_obj in self.monitored_threads.items():
                if thread_obj and thread_obj.is_alive():
                    active_threads.append(thread_name)
            
            if active_threads:
                self.memory_logger.info(f"🧵 活跃线程监控 | 运行中: {', '.join(active_threads)} | 总数: {len(active_threads)}")
            
            # 记录总线程数
            total_threads = threading.active_count()
            self.memory_logger.info(f"🧵 系统线程总数: {total_threads}")
    
    def _log_queue_status(self):
        """记录队列状态"""
        with self._lock:
            for queue_name, queue_obj in self.monitored_queues.items():
                try:
                    if hasattr(queue_obj, 'qsize'):
                        queue_size = queue_obj.qsize()
                        self.memory_logger.info(f"📦 队列监控 | {queue_name}: {queue_size} 项")
                    elif hasattr(queue_obj, '__len__'):
                        queue_size = len(queue_obj)
                        self.memory_logger.info(f"📦 队列监控 | {queue_name}: {queue_size} 项")
                    else:
                        self.memory_logger.info(f"📦 队列监控 | {queue_name}: 无法获取大小")
                except Exception as e:
                    self.memory_logger.warning(f"⚠️ 队列 {queue_name} 监控失败: {str(e)}")
    
    def log_memory_snapshot(self, context: str = ""):
        """手动记录内存快照"""
        try:
            process = psutil.Process()
            memory_info = process.memory_info()
            memory_mb = memory_info.rss / 1024 / 1024
            
            timestamp = datetime.now().strftime("%H:%M:%S")
            context_str = f" | {context}" if context else ""
            
            self.memory_logger.info(f"📸 内存快照 [{timestamp}] | {memory_mb:.1f}MB{context_str}")
            
        except Exception as e:
            self.memory_logger.error(f"❌ 内存快照失败: {str(e)}")
    
    def get_current_memory_mb(self) -> float:
        """获取当前内存使用量（MB）"""
        try:
            process = psutil.Process()
            return process.memory_info().rss / 1024 / 1024
        except:
            return 0.0